// Copyright 2025 The Drasi Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.PowerPlatform.Dataverse.Client;
using Azure.Identity;
using Drasi.Source.SDK.Models;
using Drasi.Source.SDK;

namespace DataverseReactivator.Services
{
    internal static class ServiceClientFactory
    {
        public static ServiceClient BuildClient(IConfiguration configuration, ILogger logger)
        {
            var dataverseUri = configuration.GetValue<string>("endpoint");
            if (string.IsNullOrEmpty(dataverseUri))
            {
                throw new InvalidOperationException("dataverseUri configuration is required");
            }

            var uri = new Uri(dataverseUri);
            var dataverseScope = $"{uri.Scheme}://{uri.Host}/.default";

            Azure.Core.TokenCredential credential;

            switch (configuration.GetIdentityType())
            {
                case IdentityType.MicrosoftEntraWorkloadID:
                    logger.LogInformation("Using Microsoft Entra Workload ID");
                    var managedIdentityClientId = configuration.GetValue<string>("AZURE_CLIENT_ID");
                    credential = new DefaultAzureCredential(
                        new DefaultAzureCredentialOptions
                        {
                            ManagedIdentityClientId = managedIdentityClientId
                        });
                    var serviceClient = new ServiceClient(
                        uri,
                        async (string instanceUri) =>
                        {
                            var token = await credential.GetTokenAsync(
                                new Azure.Core.TokenRequestContext(new[] { dataverseScope }),
                                default);
                            return token.Token;
                        },
                        useUniqueInstance: false,
                        logger: null);

                    return serviceClient;
                default:
                    var clientId = configuration.GetValue<string>("clientId");
                    var clientSecret = configuration.GetValue<string>("clientSecret");

                    if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret))
                    {
                        return new ServiceClient(new Uri(dataverseUri), clientId, clientSecret, false);
                    }
                    break;
            }
            throw new InvalidOperationException("No valid authentication method found in configuration");
        }
    }
}
